package com.easylinkin.linkappapi.lobar.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easylinkin.linkappapi.common.exceptions.BusinessException;
import com.easylinkin.linkappapi.common.model.RequestModel;
import com.easylinkin.linkappapi.common.service.AppSendMessageService;
import com.easylinkin.linkappapi.config.entity.Config;
import com.easylinkin.linkappapi.config.service.ConfigService;
import com.easylinkin.linkappapi.device.entity.Device;
import com.easylinkin.linkappapi.device.mapper.DeviceMapper;
import com.easylinkin.linkappapi.lobar.constant.LobarConstant;
import com.easylinkin.linkappapi.lobar.constant.LobarConstant.WaringType;
import com.easylinkin.linkappapi.lobar.constant.LobarConstant.WarningMsgTemplate;
import com.easylinkin.linkappapi.lobar.constant.LobarConstant.WarningRule;
import com.easylinkin.linkappapi.lobar.dto.GateQueryDTO;
import com.easylinkin.linkappapi.lobar.dto.UserProjectDTO;
import com.easylinkin.linkappapi.lobar.dto.excel.ExcelResultDTO;
import com.easylinkin.linkappapi.lobar.dto.excel.ExcelResultDetailDTO;
import com.easylinkin.linkappapi.lobar.dto.gate.UpGateDTO;
import com.easylinkin.linkappapi.lobar.entity.*;
import com.easylinkin.linkappapi.lobar.entity.emp.EmpUserBase;
import com.easylinkin.linkappapi.lobar.entity.emp.EmpUserBaseDTO;
import com.easylinkin.linkappapi.lobar.mapper.*;
import com.easylinkin.linkappapi.lobar.service.GateService;
import com.easylinkin.linkappapi.lobar.service.UserClockService;
import com.easylinkin.linkappapi.lobar.service.UserGateService;
import com.easylinkin.linkappapi.lobar.service.UserProjectService;
import com.easylinkin.linkappapi.lobar.util.BladeGuardApi;
import com.easylinkin.linkappapi.lobar.vo.GateRecordVo;
import com.easylinkin.linkappapi.openapi.dto.DatapushDTO;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.MessageFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 闸机表 服务实现类
 * </p>
 *
 * @author TongJie
 * @since 2022-04-13
 */
@Service
@Slf4j
public class GateServiceImpl extends ServiceImpl<GateMapper, Gate> implements GateService {

  @Resource
  private LinkappUserContextProducer linkappUserContextProducer;

  @Autowired
  private UserProjectMapper userProjectMapper;

  @Autowired
  private UserGateLinkMapper userGateLinkMapper;

  @Autowired
  private BladeGuardApi bladeGuardApi;
  @Autowired
  private UserClockService userClockService;

  @Autowired
  private UserGateService userGateService;

  @Autowired
  private UserGateMapper userGateMapper;

  @Autowired
  private WarningConfigMapper warningConfigMapper;

  @Autowired
  private UserProjectService userProjectService;
  @Autowired
  private DeviceMapper deviceMapper;
  @Autowired
  private EmpUserBaseMapper empUserBaseMapper;

  @Resource
  private EpidemicWarningMapper epidemicWarningMapper;

  @Autowired
  private AppSendMessageService appSendMessageService;

  @Autowired
  private RedisTemplate redisTemplate;

  @Autowired
  private ConfigService configService;

  /**
   * 增加
   * @param gate
   */
  @Override
  public void insert(Gate gate) {
    /**
     * 验证重复
     */
    this.checkExist(gate);
    //设置基本属性
    this.setBase(gate);
    this.save(gate);
  }

  /**
   * 根据id编辑
   * @param gate
   */
  @Override
  public void updateOne(Gate gate) {
    /**
     * 验证重复
     */
    this.checkExist(gate);
    //设置基本属性
    this.setBase(gate);
    UpdateWrapper<Gate> updateWrapper = new UpdateWrapper<>();
    updateWrapper.set("tenant_id_",gate.getTenantId())
        .set("name_",gate.getName())
        .set("brand_",gate.getBrand())
        .set("code_",gate.getCode())
        .set("position_",gate.getPosition())
        .set("status_",gate.getStatus())
        .set("direction_",gate.getDirection())
        .set("health_temperature_",gate.getHealthTemperature())
        .set("device_id_",gate.getDeviceId())
        .set("blade_guard_bind_status_",gate.getBladeGuardBindStatus())
        .set("blade_guard_project_id_",gate.getBladeGuardProjectId())
        .set("blade_guard_user_id",gate.getBladeGuardUserId())
        .set("blade_guard_jing_du",gate.getBladeGuardJingDu())
        .set("blade_guard_wei_du",gate.getBladeGuardWeiDu())
        .set("blade_guard_qrcode",gate.getBladeGuardQRCode())
        .set("blade_guard_project_name",gate.getBladeGuardProjectName())
        .set("blade_guard_project_address",gate.getBladeGuardProjectAddress())
        .set("creator_id_",gate.getCreatorId())
        .set("create_time_",gate.getCreateTime())
        .set("modify_id_",gate.getModifyId())
        .set("modify_time_",gate.getModifyTime())
        .set("remark_",gate.getRemark())
        .set("service_area",gate.getServiceArea())
        .set("access_",gate.getAccess())
        .set("in_area_",gate.getInArea())
        .set("is_record_", gate.getIsRecord())
        .eq("id",gate.getId());
    baseMapper.update(null,updateWrapper);
  }

  /**
   * 查询闸机下绑定的用户
   * @param requestModel
   * @return
   */
  @Override
  public IPage<UserProjectDTO> queryUserByPage(RequestModel<UserProject> requestModel) {
    Page page = requestModel.getPage();
    UserProject userProject = requestModel.getCustomQueryParams();
    //项目id 过滤
    userProject.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
    IPage<UserProjectDTO> gateIPage = userProjectMapper.findUserGate(page, userProject);
    gateIPage.getRecords().forEach(g ->{
      if(null != g.getBirthday()){
        g.setAge(DateUtil.age(g.getBirthday(),new Date()));
      }
    });
    return gateIPage;
  }

  /**
   * @Description: 增加闸机授权人员
   * @author kan yuanfeng
   * @date 2020/11/04 11:42
   */
  @Override
  public void insertUser(Gate gate) {
    gate.getIds().forEach(id ->{
      UserGateLink userGateLink = new UserGateLink();
      userGateLink.setUserId(id);
      userGateLink.setGateId(gate.getId());
      userGateLink.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
      userGateLink.setModifyId(linkappUserContextProducer.getCurrent().getId());
      userGateLink.setCreatorId(linkappUserContextProducer.getCurrent().getId());
      userGateLink.setCreateTime(new Date());
      userGateLink.setModifyTime(new Date());
      userGateLinkMapper.insert(userGateLink);
    });
  }

  /**
   * @Description: 解除绑定
   * @author kan yuanfeng
   * @date 2020/11/04 11:42
   */
  @Override
  public void delUser(Set<String> ids) {
    ids.forEach(id ->{
      userGateLinkMapper.deleteById(id);
    });
  }

  /**
   * @Description: 删除闸机（包含批量删除）
   * @author kan yuanfeng
   * @date 2020/11/04 11:42
   */
  @Override
  public void delBatch(Set<String> ids) {
    ids.forEach(id ->{
      //判断是否有授权人员
      QueryWrapper<UserGateLink> queryWrapper = new QueryWrapper<>();
      queryWrapper.eq("gate_id_",id);
      Integer integer = userGateLinkMapper.selectCount(queryWrapper);
      if (integer > 0){
        throw new BusinessException("该闸机已授权了人员，请删除授权后再删除闸机");
      }
      baseMapper.deleteById(id);
    });
  }

  /**
   * 闸机流水处理
   * @param datapushDTO
   */
  @Override
  public void datapushHandler(DatapushDTO datapushDTO) {
    JSONObject data = datapushDTO.getData();
    //先通过身份证号码查询对应的人员
    //通过人员id查找人员 update 20220726 kyf
//      String card = data.getString("personId");
//      String gateId = data.getString("personId");
    //通过人员id或者身份证号码查找人员 update 20220727 kyf
    String cardOrGateId = data.getString("personId");
    //设备编号查询闸机
    Gate gate = null;
    String deviceId = datapushDTO.getDevice_id();
    if (StringUtils.isNotBlank(cardOrGateId)){
      List<UserProjectDTO> userProjectDTOS;
      //先判断是否是自定义的id
      if (cardOrGateId.startsWith(Gate.getIdPre())){
        String userId = cardOrGateId.replaceAll(Gate.getIdPre(), "");
        userProjectDTOS = userProjectMapper.findByGateLinkId(Integer.valueOf(userId));
      }else {
        userProjectDTOS = userProjectMapper.findByCardOrGateId(cardOrGateId);
      }
//        List<UserProjectDTO> userProjectDTOS = userProjectMapper.findByCard(card);
      //通过闸机保存的id查找
//        List<UserProjectDTO> userProjectDTOS = userProjectMapper.findByGateId(gateId);
      //通过人员id或者身份证号码查找人员 update 20220727 kyf

      if (userProjectDTOS.size() > 0){
        UserProjectDTO userProjectDTO;
        QueryWrapper<Gate> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("code_",deviceId);
        //多人在岗时通过闸机查人员，一人在岗人员tenantId设备编号查询闸机
        if (userProjectDTOS.size() ==1){
          userProjectDTO = userProjectDTOS.get(0);
          queryWrapper.eq("tenant_id_",userProjectDTO.getTenantId());
          //根据闸机tenantId区分人员
          List<Gate> gates = baseMapper.selectList(queryWrapper);
          if (null != gates && gates.size() > 0){
            gate = gates.get(0);
          }
        }else {
          //根据闸机tenantId区分人员
          List<Gate> gates = baseMapper.selectList(queryWrapper);
          Set<String> tIds = gates.stream().map(g -> g.getTenantId())
                  .collect(Collectors.toSet());
          List<UserProjectDTO> projectDTOS = userProjectDTOS.stream()
                  .filter(u -> tIds.contains(u.getTenantId()))
                  .collect(Collectors.toList());
          if (projectDTOS.size() > 0){
            userProjectDTO = projectDTOS.get(0);
          }else {
            //万一取不到就随机取一个
            userProjectDTO = userProjectDTOS.get(0);
          }
          List<Gate> gateList = gates.stream()
                  .filter(g -> userProjectDTO.getTenantId().equals(g.getTenantId()))
                  .collect(Collectors.toList());
          if (gateList.size() > 0){
            gate = gateList.get(0);
          }
        }
        //考勤
        if (gate != null && Integer.valueOf(1).equals(gate.getIsRecord())) {
          userProjectDTO.setIsRecord(1);
        } else {
          userProjectDTO.setIsRecord(0);
        }
        toAddUserClock(data, userProjectDTO, gate);
        //健康码
        //判断是否支持健康码
        if (gate != null && Integer.valueOf(1).equals(gate.getHealthTemperature())){
          toAddUserGate(data, userProjectDTO, gate);
        }
        if(StringUtils.isNotEmpty(userProjectDTO.getCard())){
          //上传卫士
          tobladeGuard(data, userProjectDTO, gate);
        }
      }
    }
  }

  /**
   * 同步授权人员
   * @param id
   */
  @Override
  public ExcelResultDTO upUserToGate(String id){
    //查询闸机
    Gate gate = baseMapper.selectById(id);
    String code = gate.getCode();
    if (StringUtils.isBlank(code)){
      throw new BusinessException("闸机没有填写序列号");
    }else {
      //查询真实设备
      //查询在不在设备库里
      Set<String> codes = new HashSet<>();
      codes.add(code);
      List<Device> devices = deviceMapper.findDeviceByCodesGlobal(codes,gate.getTenantId());
      if (devices.size() < 1){
        throw new BusinessException("闸机没有绑定到真实设备");
      }
    }
    if (StringUtils.isBlank(gate.getAccess()) || !gate.getAccess().contains("1")){
      throw new BusinessException("闸机没有施工云通行权限");
    }
    ExcelResultDTO excelResultDTO = getResultDTO(gate);
    return excelResultDTO;
  }

  /**
   * 查询可选择的下拉闸机设备选项
   * @param code  编辑时带上自身数据设备code
   */
  @Override
  public List<Device> getDeviceList(String code) {
    //已经绑定闸机的
    List<Gate> gates = baseMapper.selectList(new QueryWrapper<>());
    List<String> codos = gates.stream().filter(g -> StringUtils.isNotBlank(g.getCode()))
            .map(Gate::getCode).collect(Collectors.toList());
    //面板机配置
    List<String> deviceUnitNames = new ArrayList<>();
    Config config = configService.getOneByKeyAndTenantId("LABOR_DEVICE_TYPES",null);
    if (null != config && StringUtils.isNotBlank(config.getValue())){
      deviceUnitNames = Arrays.asList(config.getValue().split(","));
    }
    List<Device> deviceList = deviceMapper.getDeviceListForGate(codos,code,deviceUnitNames);
    //编辑时处理
    if (StringUtils.isNotBlank(code)){
      List<Device> devices = deviceList.stream().filter(d -> code.equals(d.getCode())).collect(Collectors.toList());
      //移除包含code的
      deviceList.removeIf(d-> code.equals(d.getCode()));
      if (devices.size() > 0){
        //修改的那个放在第一位
        deviceList.add(0,devices.get(0));
      }
    }
    return deviceList;
  }

  /**
   * @Description: 删除闸机关联人员
   * @author kan yuanfeng
   * @date 2020/11/04 11:42
   */
  @Override
  public void deleteLink(Set<Integer> ids) {
    ids.forEach(id ->{
      UserGateLink userGateLink = userGateLinkMapper.selectById(id);
      if (null != userGateLink){
        //查询闸机对应code
        if (StringUtils.isNotBlank(userGateLink.getGateId())){
          Gate gate = baseMapper.selectById(userGateLink.getGateId());
          if (null != gate && StringUtils.isNotBlank(gate.getCode())){
            //查询对应用户信息
            EmpUserBase empUserBase = empUserBaseMapper.selectById(userGateLink.getUserId());
            if (null != empUserBase){
              userProjectService.delGate(empUserBase,gate.getCode(),true);
            }else {
              userGateLinkMapper.deleteById(id);
            }
          }else {
            throw new BusinessException("闸机对应的设备不存在");
          }
        }
      }
    });
  }

  /**
   * @param gate
   * @return
   */
  private ExcelResultDTO getResultDTO(Gate gate){
    ExcelResultDTO excelResultDTO = new ExcelResultDTO();
    //查询已经下发到闸机的人员
    QueryWrapper<UserGateLink> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("gate_id_",gate.getId());
    List<UserGateLink> gateLinks = userGateLinkMapper.selectList(queryWrapper);
    Set<String> list = gateLinks.stream().map(g -> g.getUserId()).collect(Collectors.toSet());
    gate.setIds(list);
    //查询需要同步的人员
    List<EmpUserBase> empUserBases = empUserBaseMapper.queryByGate(gate);
    //过滤人员和空人员
    List<EmpUserBase> userBases = empUserBases.stream()
        .filter(e -> null != e && StringUtils.isNotBlank(e.getId()) && !list.contains(e.getId()))
        .collect(Collectors.toList());
    if (userBases.size() < 1){
      throw new BusinessException("没有需要同步的人员");
    }
    //另起一个线程处理下发
    setToRedis(gate.getId(),null);
    new Thread(() ->{
      try {
        excelResultDTO.setSum(userBases.size());
        List<ExcelResultDetailDTO> sonList = new ArrayList<>();
        userBases.forEach(e -> {
          ExcelResultDetailDTO detailDTO = userProjectService.userToOneGate(e, gate);
          if (Integer.valueOf(1).equals(detailDTO.getType())){
            sonList.add(detailDTO);
          }
        });
        excelResultDTO.setExcelResultDetailDTOS(sonList);
        excelResultDTO.setFail(sonList.size());
        excelResultDTO.setSuccess(excelResultDTO.getSum()-sonList.size());
        //得到的结果存放redis
        setToRedis(gate.getId(),excelResultDTO);
      } catch (Exception e) {
        //异常也要保存结果
        setToRedis(gate.getId(),excelResultDTO);
      }
    }).start();
    return excelResultDTO;
  }

  /**
   * 开始下发时存一个初始结果到redis
   * @param gateId
   */
  private void setToRedis(String gateId,ExcelResultDTO excelResultDTO) {
    UpGateDTO upGateDTO = (UpGateDTO)redisTemplate.opsForValue().get(Gate.getRedisIdPre()+gateId);
    if (null == upGateDTO){
      upGateDTO = new UpGateDTO();
    }
    if (null != excelResultDTO){
      upGateDTO.setUpTime(new Date());
      upGateDTO.setDone(true);
    }else {
      upGateDTO.setDone(false);
    }
    upGateDTO.setExcelResultDTO(excelResultDTO);
    redisTemplate.opsForValue().set(Gate.getRedisIdPre()+gateId,upGateDTO);
  }

  /**
   * 健康码
   * @param data
   * @param userProjectDTO
   */
  private void toAddUserGate(JSONObject data, UserProjectDTO userProjectDTO,Gate gate) {
    UserGate userGate = new UserGate();
    userGate.setTenantId(userProjectDTO.getTenantId());
    userGate.setType(2);
    userGate.setUserId(userProjectDTO.getUserId());
    userGate.setUserName(userProjectDTO.getUserName());
    userGate.setGateId(gate.getId());
    userGate.setCompanyProjectId(userProjectDTO.getCompanyProjectId());
    userGate.setGroupId(userProjectDTO.getGroupId());
    userGate.setTime(data.getDate("capTime"));
    userGate.setPhoto(data.getString("closeupPic"));
//    userGate.setPhoto()
    userGate.setTemperature(data.getDouble("temperature"));
    //健康码
    log.info("获取流水健康码healthCode： "+ data.getString("healthCode"));
    String healthCode = data.getString("healthCode").substring(0,2);
//    健康码(1绿码，2黄码，3灰码，4红码)
//    String[] codes = {"","绿码","黄码","灰码","红码"};
    userGate.setHealthCode(Arrays.asList(LobarConstant.codes).indexOf(healthCode));
    //查询当天有没有记录
    QueryWrapper<UserGate> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("user_id_",userProjectDTO.getUserId())
        .eq("tenant_id_",userProjectDTO.getTenantId())
        .ge("time_",DateUtil.beginOfDay(new Date()))
        .le("time_",DateUtil.endOfDay(new Date()));
    List<UserGate> userGates = userGateMapper.selectList(queryWrapper);
    if (null != userGates && userGates.size() > 0){
      userGate.setId(userGates.get(0).getId());
      userGateService.updateOne(userGate);
    }else {
      userGateService.insert(userGate);
    }
    // 疫情预警
    epidemicWarning(userProjectDTO,userGate.getTemperature(),userGate.getHealthCode());
  }

  private void epidemicWarning(UserProjectDTO userProjectDTO,Double temperature,Integer healthCode){
    QueryWrapper<WarningConfig> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("tenant_id_",userProjectDTO.getTenantId());
    queryWrapper.orderByDesc("create_time_");
    List<WarningConfig> warningConfigs = warningConfigMapper.selectList(queryWrapper);
    if(CollectionUtil.isEmpty(warningConfigs)){
      return;
    }
    WarningConfig warningConfig = warningConfigs.get(0);
    if(null == warningConfig){
      return;
    }
    Boolean healthCodeFlag = false;
    Boolean temperatureFlag = false;
    String healthWarningCodes = warningConfig.getHealthCode();
    if(StringUtils.isNotEmpty(healthWarningCodes)){
      List<String> healthWarningCodeList = Arrays.asList(healthWarningCodes.split(","));
      if(healthWarningCodeList.contains(String.valueOf(healthCode))){
        healthCodeFlag = true;
      }
    }
    if(temperature > warningConfig.getTemperature()){
      temperatureFlag = true;
    }
    if(healthCodeFlag||temperatureFlag){
      EpidemicWarning epidemicWarning = new EpidemicWarning();
      epidemicWarning.setUserId(userProjectDTO.getUserId());
      epidemicWarning.setTenantId(userProjectDTO.getTenantId());
      epidemicWarning.setHealthCode(healthCode);
      epidemicWarning.setTemperature(temperature);
      epidemicWarning.setWarningTime(new Date());
      EmpUserBaseDTO empUserBaseDTO = userProjectService.getByUserIdAndTenantIEmp(userProjectDTO.getUserId(),userProjectDTO.getTenantId());
      String warningMsg = "";
      if(null != empUserBaseDTO){
        if(!healthCodeFlag&&temperatureFlag){
          epidemicWarning.setType(1);// 体温异常
          epidemicWarning.setWarningRule(MessageFormat.format(WarningRule.TEMPERATURE_WARNING.getRule(),
              empUserBaseDTO.getName(),
              empUserBaseDTO.getUserProject().getGroupName(),
              empUserBaseDTO.getUserProject().getCompanyName(),
              warningConfig.getTemperature()));
          warningMsg = MessageFormat.format(WarningMsgTemplate.TEMPERATURE_WARNING.getRule(),
              DateUtil.format(new Date(),
                  com.easylinkin.linkappapi.common.utils.DateUtil.DATE_TIME_FORMAT_MINUTE),
              empUserBaseDTO.getUserProject().getCompanyName(),
              empUserBaseDTO.getUserProject().getGroupName(),
              empUserBaseDTO.getName(),
              temperature);
        }
        if(healthCodeFlag&&!temperatureFlag){
          epidemicWarning.setType(2);// 健康码异常
          epidemicWarning.setWarningRule(MessageFormat.format(WarningRule.HEALTH_CODE_WARNING.getRule(),
              empUserBaseDTO.getName(),
              empUserBaseDTO.getUserProject().getGroupName(),
              empUserBaseDTO.getUserProject().getCompanyName()));
          warningMsg = MessageFormat.format(WarningMsgTemplate.HEALTH_CODE_WARNING.getRule(),
              DateUtil.format(new Date(),
                  com.easylinkin.linkappapi.common.utils.DateUtil.DATE_TIME_FORMAT_MINUTE),
              empUserBaseDTO.getUserProject().getCompanyName(),
              empUserBaseDTO.getUserProject().getGroupName(),
              empUserBaseDTO.getName(),
              LobarConstant.codes[healthCode]);
        }
        if(healthCodeFlag&&temperatureFlag){
          epidemicWarning.setType(3);// 体温异常&健康码异常
          epidemicWarning.setWarningRule(MessageFormat.format(WarningRule.HEALTH_CODE_TEMPERATURE_WARNING.getRule(),
              empUserBaseDTO.getName(),
              empUserBaseDTO.getUserProject().getGroupName(),
              empUserBaseDTO.getUserProject().getCompanyName(),
              warningConfig.getTemperature()));
          warningMsg = MessageFormat
              .format(WarningMsgTemplate.HEALTH_CODE_TEMPERATURE_WARNING.getRule(),
                  DateUtil.format(new Date(),
                      com.easylinkin.linkappapi.common.utils.DateUtil.DATE_TIME_FORMAT_MINUTE),
                  empUserBaseDTO.getUserProject().getCompanyName(),
                  empUserBaseDTO.getUserProject().getGroupName(),
                  empUserBaseDTO.getName(),
                  LobarConstant.codes[healthCode],
                  temperature);
        }
      }
      epidemicWarning.setCreateTime(new Date());
      epidemicWarning.setModifyTime(new Date());
      //20220915增加获取配置逻辑
      Integer healthCodeSwitch = warningConfig.getHealthCodeSwitch();
      Integer temperatureSwitch = warningConfig.getTemperatureSwitch();
      if ((temperatureSwitch != null && temperatureSwitch.intValue() == 1) || (healthCodeSwitch != null && healthCodeSwitch.intValue() == 1)) {
        epidemicWarningMapper.insert(epidemicWarning);
        appSendMessageService
            .sendAppWarning(epidemicWarning.getId(), WaringType.EPIDEMIC_WARNING, warningMsg,
                userProjectDTO.getTenantId());
      }
    }
  }


  /**
   * 考勤
   * @param data
   * @param userProjectDTO
   */
  private void toAddUserClock(JSONObject data, UserProjectDTO userProjectDTO,Gate gate) {
    UserClock userClock = new UserClock();
    userClock.setUserId(userProjectDTO.getUserId());
    userClock.setDirection(gate.getDirection());
    userClock.setTenantId(userProjectDTO.getTenantId());
    userClock.setType(2);
    userClock.setCompanyProjectId(userProjectDTO.getCompanyProjectId());
    userClock.setGroupId(userProjectDTO.getGroupId());
    userClock.setUserName(userProjectDTO.getUserName());
    userClock.setClockTime(data.getDate("capTime"));
    userClock.setPhoto(data.getString("closeupPic"));
    //2022 10 21记录闸机编码和区域
    userClock.setGateCode(gate.getCode());
    userClock.setServiceArea(gate.getServiceArea());
    userClock.setIsRecord(userProjectDTO.getIsRecord());
    //记录进入区域
    if (Integer.valueOf(1).equals(userClock.getDirection())){
      userClock.setOnArea(gate.getServiceArea());
    }else {
      userClock.setOnArea(gate.getInArea());
    }
    //考勤时间
    userClockService.insert(userClock);
  }

  @Override
  public IPage<Gate> queryListByPage(RequestModel<Gate> requestModel) {
    Page page = requestModel.getPage();
    Gate gate = requestModel.getCustomQueryParams();
    //项目id 过滤
    gate.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
    IPage<Gate> gateIPage = baseMapper.queryListByPage(page, gate);
    return gateIPage;
  }

  /**
  * @Description: 闸机记录查询
  * @Param: [requestModel]
  * @return: com.baomidou.mybatisplus.core.metadata.IPage<com.easylinkin.linkappapi.lobar.vo.GateRecordVo>
  * @Author: 胡明威
  * @Date: 2023/11/8
  */
  @Override
  public IPage<GateRecordVo> selectGateRecords(RequestModel<GateQueryDTO> requestModel) {
    Page page = requestModel.getPage();
    GateQueryDTO gateQueryDTO = requestModel.getCustomQueryParams();
    // 设置租户ID
    gateQueryDTO.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
    // 执行查询
    IPage<GateRecordVo> gateRecordVoIPage = baseMapper.selectGateRecords(page, gateQueryDTO);
    return gateRecordVoIPage;
  }

  /**
   * 验证重复
   */
  private void checkExist(Gate gate) {
    QueryWrapper<Gate> queryWrapper1 = new QueryWrapper<>();
    //设置判断重复条件
    String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
    queryWrapper1.eq("name_",gate.getName())
        .eq("tenant_id_", tenantId);
    //编辑的时候存在id
    Optional.ofNullable(gate.getId()).ifPresent(id -> queryWrapper1.ne("id",gate.getId()));
    Integer integer = baseMapper.selectCount(queryWrapper1);
    if (integer>0){
      throw new BusinessException("该闸机已存在");
    }
    if (StringUtils.isNotBlank(gate.getCode())){
      QueryWrapper<Gate> queryWrapper2 = new QueryWrapper<>();
      queryWrapper2.eq("code_",gate.getCode());
      //编辑的时候存在id
      Optional.ofNullable(gate.getId()).ifPresent(id -> queryWrapper2.ne("id",gate.getId()));
      List<Gate> gates = baseMapper.selectList(queryWrapper2);
      if (gates.size() > 0){
        long count1 = gates.stream().filter(g -> tenantId.equals(g.getTenantId())).count();
        long count2 = gates.stream().filter(g -> !tenantId.equals(g.getTenantId())).count();
        if (count1>0){
          throw new BusinessException("该闸机序列号已经绑定其他闸机");
        }else if (count2>0){
          throw new BusinessException("该闸机序列号已经绑定其他项目闸机");
        }
      }
    }
  }

  /**
   * 设置基本属性
   * @param gate
   */
  private void setBase(Gate gate) {
    gate.setModifyTime(new Date());
    gate.setModifyId(linkappUserContextProducer.getCurrent().getId());
    //没有id就是新增,有就是编辑
    if (StringUtils.isBlank(gate.getId())){
      gate.setCreatorId(linkappUserContextProducer.getCurrent().getId());
      gate.setCreateTime(new Date());
      gate.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
    }
  }

  /**
   * 闸机工地卫士代打卡
   * @param data
   * @param user
   * @param gate
   */
  private void tobladeGuard(JSONObject data, UserProjectDTO user,Gate gate) {
    if(!Integer.valueOf(1).equals(gate.getBladeGuardBindStatus())){
      return;
    }
    bladeGuardApi.scanHealthCode(gate.getBladeGuardUserId(), gate.getBladeGuardProjectId(),
        gate.getBladeGuardWeiDu(), gate.getBladeGuardJingDu(), user.getCard(),
        data.getString("personName"), user.getType(), user.getTelephone(),
        gate.getBladeGuardProjectName(), gate.getBladeGuardProjectAddress(),
        data.getDate("capTime"));

  }
}
